﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using NRemedy;
using BMC.ARSystem;
using System.CodeDom;


namespace Wicresoft.NRemedy.VS10Addin.UI
{
    public class CodeLoader
    {
        public event SendModelListDelegation OnGenerateCompeleted;

        private string _server;
        private string _user;
        private string _password;
        private List<FormListItemData> _forms;

        public CodeLoader()
        {
        }

        //这个函数在UI线程中执行 
        public void GenerateCodes(string server, string user, string password, List<FormListItemData> forms)
        {
            _server = server;
            _user = user;
            _password = password;
            _forms = forms;
            Thread thread = new Thread(new ThreadStart(LoadInternal));
            thread.Start();
        }
        //这个函数在新的线程中执行 
        private void LoadInternal()
        {
            List<ModelInfo> rdata = new List<ModelInfo>();

            using (ARLoginContext context = new ARLoginContext(_server, _user, _password))
            {
                CSharpModelGenerator generator = new CSharpModelGenerator(context);
                
                foreach (var form in _forms.Where(f => f.IsChecked))
                {
                    if (form == null) continue;
                    CSharpModelGeneratorFactory csmgdf = new CSharpModelGeneratorFactory
                        (form.PropertyMapping.Where(p=>p.IsChecked).Select(p=>p.RemedyFieldName).ToList());
                    CodeCompileUnit ccu = generator.GenerateClassByFormName(form.FormName, csmgdf);
                    //string code = generator.GenerateClassByFormName(input);
                    string code = generator.GenerateCodeByCodeCompileUnit(ccu);

                    ModelInfo mi = new ModelInfo();
                    mi.FormName = form.FormName;
                    mi.ClassName = ccu.Namespaces[0].Types[0].Name;
                    mi.ModelCode = code;

                    mi.Properties = new List<ModelPropertyInfo>();
                    foreach (CodeTypeMember member in ccu.Namespaces[0].Types[0].Members)
                    {
                        if (member is CodeMemberProperty)
                        {
                            CodeMemberProperty m = member as CodeMemberProperty;
                            ModelPropertyInfo mpi = new ModelPropertyInfo();
                            mpi.ModelPropertyName = m.Name;

                            CodeAttributeDeclaration attribute = null;
                            foreach (CodeAttributeDeclaration c in m.CustomAttributes)
                            {
                                if (c.AttributeType.BaseType == "NRemedy.ARFieldAttribute")
                                {
                                    attribute = c;
                                    break;
                                }
                            }

                            if (attribute == null) continue;
                            foreach (CodeAttributeArgument arg in attribute.Arguments)
                            {
                                if (arg.Name == "DatabaseID")
                                    mpi.RemedyFieldId = ((CodePrimitiveExpression)arg.Value).Value.ToString();
                                if (arg.Name == "DatabaseName")
                                    mpi.RemedyFieldName = ((CodePrimitiveExpression)arg.Value).Value.ToString();
                            }

                            mi.Properties.Add(mpi);
 
                        }
                    }

                    rdata.Add(mi);
                }

            }

            if (OnGenerateCompeleted != null)
            {
                //获取myDelegate的目标对象，这里将是Form1的实例 
                Control control = OnGenerateCompeleted.Target as Control;
                //如果目标对象是个Control的话 
                if (control != null)
                {
                    //通过调用form的invoke，把委托指向的函数NotifyReceiver送到UI线程上执行 
                    control.Invoke(OnGenerateCompeleted, rdata);
                }
                //如果目标对象不是Control，则直接执行委托 
                else
                {
                    OnGenerateCompeleted(rdata);
                }
            } 

        } 
    }
}
